﻿using System;
using System.Net;
using System.Text.RegularExpressions;
using OpenWaves.Caching;

namespace OpenWaves.Video.Vimeo
{
    public class VimeoApi : VideoApi, IVideoWebsiteApi
    {
        public static readonly string VideoEmbedUrlFormat = "http://player.vimeo.com/video/{0}?api=1&id={1}";
        public static readonly string VimeoApiUrlFormat = "http://vimeo.com/api/v2/video/{0}.xml";
        public static readonly Regex VimeoVideoRegex = new Regex(@"vimeo\.com/(?:.*#|.*/videos/)?([0-9]+)");


        private readonly Func<Url, string> webClient;
        private readonly IConcurrentCache<IVideo> videoCache;
        private Match match;

        public VimeoApi()
            : this(new ConcurrentCache<IVideo>(Cache.Null<IVideo>()))
        {
        }

        public VimeoApi(IConcurrentCache<IVideo> videoCache) : this(videoCache, GetDefaultWebClient())
        {
        }


        public VimeoApi(IConcurrentCache<IVideo> videoCache, Func<Url, string> webClient)
        {
            this.videoCache = videoCache;
            this.webClient = webClient;
        }

        public IVideo GetVideo(string url)
        {
            string videoId;
            bool isSupported = IsSupported(url, out videoId);

            if (!isSupported)
            {
                return null;
            }

            try
            {
                return videoCache.GetOrCreate(url, () =>
                {
                    string apiUrl = string.Format(VimeoApiUrlFormat, videoId);
                    string xmlString = webClient(Url.Parse(apiUrl));
                    VimeoVideo video = RestDeserializer.Deserialize<VimeoVideos>(xmlString).Video;
                    return CacheEntry.FromValue((IVideo) video, TimeSpan.FromHours(1));
                
                });
            }
            catch (WebException webException)
            {
                return null;
            }
        }

        public bool IsSupported(string url)
        {
            string videoId;
            return IsSupported(url, out videoId);
        }

        public bool IsSupported(string url, out string videoId)
        {
            match = VimeoVideoRegex.Match(url);
            videoId = match.Groups[1].Value;
            return match.Success;
        }
    }
}